package ch5;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Semaphore;

/**
 * 带流量控制功能的传输通道
 * Semaphore：相当于虚拟资源配额管理器，用来控制同一时间内对虚拟资源的访问次数
 * 相应代码在访问虚拟资源前必须先申请相应的配额，并在访问资源结束后返还相应的资源
 * 在本例中，虚拟资源就是 队列
 */

public class SemaphoreBasedChannel<P> implements Channel<P>{
    private final BlockingQueue<P> queue;
    private final Semaphore semaphore;

    /**
     * @param queue      阻塞队列，通常是一个无界阻塞队列
     * @param flowLimit  流量限制数
     */
    public SemaphoreBasedChannel(BlockingQueue<P> queue, int flowLimit) {
        this(queue, flowLimit, false);
    }

    public SemaphoreBasedChannel(BlockingQueue<P> queue, int flowLimit, boolean isFair) {
        this.queue = queue;
        this.semaphore = new Semaphore(flowLimit, isFair);
    }


    @Override
    public void put(P product) throws InterruptedException {
        // 申请一个配额
        semaphore.acquire();
        try {
            queue.put(product);
        } finally {
            semaphore.release();
        }
    }

    @Override
    public P take() throws InterruptedException {
        return queue.take();
    }
}
